(function () {
  function getUrlQueryString(key) {
    var query = location.search;

    if (!query) {
      return '';
    }

    var matchPair = query.replace(/^\?/, '').split('&').map(function (item) {
      var pair = item.split('=');
      return {
        key: pair[0],
        value: pair[1] 
      };
    }).filter(function (item) {
      return item.key === key;
    });

    return matchPair[0].value || '';
  }
  var app = angular.module('app', ['angularFileUpload']);
  app.run(function ($rootScope) {
    $rootScope.iconMap = {
      'jpg': 'fa-image',
      'png': 'fa-image',
      'pdf': 'fa-file-pdf-o',
      'doc': 'fa-file-word-o',
      'docx': 'fa-file-word-o',
      'xls': 'fa-file-excel-o',
      'xlsx': 'fa-file-excel-o',
      'ppt': 'fa-file-powerpoint-o',
      'pptx': 'fa-file-powerpoint-o',
      'rar': 'fa-file-archive-o',
      'zip': 'fa-file-zip-o',
      'mp3': 'fa-file-sound-o',
      'mp4': 'fa-file-video-o',
      '_dir_': 'fa-folder-o',
      '_file_': 'fa-file-o',
      '_root_': 'fa-folder-o'
    };
    $rootScope.typeList = [
        'jpg',
        'png',
        'pdf',
        'doc',
        'docx',
        'xls',
        'xlsx',
        'ppt',
        'pptx',
        'rar',
        'zip',
        'mp3',
        'mp4'
      ];
  });
  app.filter('fileIcon', function ($rootScope) {
    return function (file) {
      var extname = '';
      var iconMap = $rootScope.iconMap;

      if (file.type === '_dir_') {
        return iconMap._dir_;
      }
      
      try {
        extname = /^.*\.(\w+)$/.exec(file.name.toLowerCase())[1];
      } catch (err) {

      }

      return !iconMap[extname] ? iconMap._file_ : iconMap[extname];
    };
  }).filter('formatFileSize', function () {
    return function (fileSize) {
      var GB = 1024 * 1024 * 1024,
          MB = 1024 * 1024,
          KB = 1024;
      if (!fileSize) {
        return '-';
      }

      if (fileSize > GB) {
        return parseFloat(fileSize / GB, 2).toFixed(2) + 'G'; 
      } else if (fileSize > MB) {
        return parseFloat(fileSize / MB, 2).toFixed(2) + 'M'; 
      } else if (fileSize > KB) {
        return parseFloat(fileSize / KB, 2).toFixed(2) + 'K';
      } else {
        return fileSize;
      }
    };
  }).filter('formatDir', function () {
    return function (dirname) {
      return ('_root_' === dirname) ? '全部文件' : dirname;
    };
  });
  app.controller('FileCtrl', function ($scope, $rootScope, $http, $upload, $interval) {

    function hideModalAfterSeconds(count) {
      $interval(function () {
        $scope.countDown--;

        if (0 === $scope.countDown) {
          $('#uploadFileModal').modal('hide');
        }

      }, 1000, count);
    }

    function handleUploadResult() {
      var count = getFileUploadSuccessCount($scope.uploadFileList);
      $scope.uploadFileSuccessCount = count;
      $scope.uploadFileStatus = (count === -1 ? 'progress' : 'done');

      if ($scope.uploadFileStatus === 'done') {
        hideModalAfterSeconds(5);
      }
    }

    function getFileUploadSuccessCount(uploadFileList) {
      var count = -1, isAllFinished = uploadFileList.every(function (file) {
        return file.status !== 'progress';
      });

      if (isAllFinished) {
        count = uploadFileList.filter(function (file) {
          return file.status === 'ok';
        }).length;
      }
       
      return count;
    }

    function sortByType(file) {
      var extname = '';
      var typeList = $rootScope.typeList;

      try {
        extname = /^.*\.(\w+)$/.exec(file.name.toLowerCase())[1];
      } catch (err) {

      }

      if (file.type === '_dir_') {
        return -1;
      }

      return (typeList.indexOf(extname) === -1) ? 100 : typeList.indexOf(extname);
    }

    $scope.tab = getUrlQueryString('tab') || 'all';

    $scope.dir = {};
    $scope.dir.root = {
      _id: $('[name=rootDir]').val(),
      name: '_root_'
    };
    $scope.dir.current = $scope.dir.root;
    $scope.dir.tree = [];
    $scope.dir.tree.push($scope.dir.root);

    $scope.fileList = [];
    $scope.uploadFileList = [];
    $scope.uploadFileStatus = 'progress';
    $scope.uploadFileSuccessCount = -1;

    $scope.$watch('files', function () {
      $scope.upload($scope.files);
    });

    $scope.upload = function (files) {
      var dirId = $scope.dir.current._id;

      if (files && files.length) {

        $scope.uploadFileList = [];
        $scope.uploadFileStatus = 'progress';
        $scope.uploadFileSuccessCount = -1;
        $scope.countDown = 5;

        if (files.length > 10) {
          alert('每次最多只能上传10个文件！');
          return false;
        }

        $('#uploadFileModal').modal('show');

        files.forEach(function (item) {
          var file = item, uploadFile = {
            name: item.name,
            status: 'progress',
            percentage: 0
          };

          $scope.uploadFileList.push(uploadFile);

          $upload.upload({
            url: '/files',
            method: 'POST',
            file: file,
            fields: {
              dir: dirId
            }
          }).progress(function (evt) {
            var progressPercentage = parseInt(100.0 * evt.loaded / evt.total, 10);
            uploadFile.percentage = progressPercentage;
          }).success(function (data, status, headers, config) {
            uploadFile.status = 'ok';
            handleUploadResult();
            $scope.list($scope.dir.current);
          }).error(function (data, status, headers, config) {
            uploadFile.status = 'fail';
            handleUploadResult();
          });
        });
      }
    };

    $scope.list = function (dir) {

      $http.post('/files/list', {
        dir: dir._id,
        tab: $scope.tab
      }).success(function (data, status, headers, config) {
        var idx;
        $scope.fileList = _.sortBy(_.sortBy(data, 'name'), sortByType);
        $scope.selectAll = false;

        if (dir.name !== '_root_') {
          idx = $scope.dir.tree.indexOf(dir);

          if (idx === -1) {
            $scope.dir.tree.push(dir);
          } else {
            $scope.dir.tree.splice(idx + 1);
          }

          $scope.dir.current = dir;
        } else {
          $scope.dir.tree = [];
          $scope.dir.tree.push($scope.dir.root);
          $scope.dir.current = $scope.dir.root;
        }

        if ($('.file_list').is(':hidden')) {
          $('.file_list').fadeIn(200);
        }

      }).error(function (data, status, headers, config) {
        alert('获取目录失败！');
      });
    };

    $scope.createDir = function () {
      var dirId = $scope.dir.current._id;

      if (!$scope.dirname) {
        alert('请输入目录名称!');
        return false;
      }

      $http.post('/files', {
        name: $scope.dirname,
        dir: dirId,
        type: '_dir_'
      }).success(function (data, status, headers, config) {
        $scope.list($scope.dir.current);
      }).error(function (data, status, headers, config) {
        alert("创建目录失败！");
      });
    };

    $scope.readFile = function (id) {
      $http.get('/files/' + id).success(function (data, status, headers, config) {
        $scope.list($scope.dir.current);
      }).error(function (data, status, headers, config) {
        alert("创建目录失败！");
      });
    };

    $scope.removeFiles = function () {
      var selectedFiles = '',
          containDir = false;

      selectedFiles = $scope.fileList.filter(function (file) {
        return file.selected === true;
      }).map(function (file) {

        if (file.type === '_dir_') {
          containDir = true;
        }

        return file._id;
      }).join(',');

      if(!selectedFiles) {
        alert('请选择文件进行删除！');
      }

      if (containDir && !confirm('选中的文件中包含目录，是否继续操作？')) {
        return false;
      }

      $http.post('/files/remove', {
        ids: selectedFiles,
        dir: $scope.dir.current._id
      }).success(function (data, status, headers, config) {
        $scope.list($scope.dir.current);
      }).error(function (data, status, headers, config) {
        alert("删除文件失败！");
      });
    };

    $scope.toggleAllSelect = function () {
      $scope.fileList.forEach(function (file) {
        file.selected = $scope.selectAll ? true : false;
      });
    };

    $scope.list($scope.dir.root);
  });
  angular.bootstrap(document, ['app']);
})();